Creating lock adapters
Implementing your custom ILockAdapter
In order to create an adapter you need to implement the ILockAdapter
contract:
// filename: MyLockAdapter.ts
import type { ILockAdapter } from "@daiso-tech/core/lock/contracts";
import type { TimeSpan } from "@daiso-tech/core/utilities";
export class MyLockAdapter implements ILockAdapter {
acquire(
key: string,
owner: string,
ttl: TimeSpan | null,
): PromiseLike<boolean> {
throw new Error("Method not implemented.");
}
release(key: string, owner: string): PromiseLike<boolean> {
throw new Error("Method not implemented.");
}
forceRelease(key: string): PromiseLike<void> {
throw new Error("Method not implemented.");
}
refresh(key: string, owner: string, ttl: TimeSpan): PromiseLike<boolean> {
throw new Error("Method not implemented.");
}
}
The ILockAdapter
contract uses PromiseLike
instead of Promise
to maintain compatibility with:
- Native JavaScript Promises
- Alternative promise libraries (e.g., Bluebird)
- Any Promise/A+ compliant implementation
This provides flexibility while ensuring standard promise behavior is maintained.
Key benefits:
- Works across different promise implementations (good for integrating legacy code)
- Maintains type safety while being less restrictive
In order to use async function you need to replace PromiseLike
with Promise
:
// filename: MyLockAdapter.ts
import type { ILockAdapter } from "@daiso-tech/core/lock/contracts";
import type { TimeSpan } from "@daiso-tech/core/utilities";
export class MyLockAdapter implements ILockAdapter {
async acquire(
key: string,
owner: string,
ttl: TimeSpan | null,
): Promise<boolean> {
throw new Error("Method not implemented.");
}
async release(key: string, owner: string): Promise<boolean> {
throw new Error("Method not implemented.");
}
async forceRelease(key: string): Promise<void> {
throw new Error("Method not implemented.");
}
async refresh(key: string, owner: string, ttl: TimeSpan): Promise<boolean> {
throw new Error("Method not implemented.");
}
}
Testing your custom ILockAdapter
We provide a complete test suite to verify your event bus adapter implementation. Simply use the lockAdapterTestSuite
function:
- Preconfigured Vitest test cases
- Standardized event bus behavior validation
- Common edge case coverage
Usage example:
// filename: MyLockAdapter.test.ts
import { beforeEach, describe, expect, test } from "vitest";
import { lockAdapterTestSuite } from "@daiso-tech/core/lock/test-utilities";
import { MemoryLockAdapter } from "./MemoryLockAdapter.js";
describe("class: MyLockAdapter", () => {
lockAdapterTestSuite({
createAdapter: () => new MemoryLockAdapter(),
test,
beforeEach,
expect,
describe,
});
});
Implementing your custom IDatabaseLockAdapter
We provide an additional contract IDatabaseLockAdapter
for building custom lock adapters tailored to databases:
// MyDatabaseLockAdapter.ts
import type {
ILockData,
IDatabaseLockAdapter,
} from "@daiso-tech/core/lock/contracts";
export class MyDatabaseLockAdapter implements IDatabaseLockAdapter {
insert(
key: string,
owner: string,
expiration: Date | null,
): PromiseLike<void> {
throw new Error("Method not implemented.");
}
update(
key: string,
owner: string,
expiration: Date | null,
): PromiseLike<number> {
throw new Error("Method not implemented.");
}
remove(key: string, owner: string | null): PromiseLike<void> {
throw new Error("Method not implemented.");
}
refresh(key: string, owner: string, expiration: Date): PromiseLike<number> {
throw new Error("Method not implemented.");
}
find(key: string): PromiseLike<ILockData | null> {
throw new Error("Method not implemented.");
}
}
The IDatabaseLockAdapter
contract uses PromiseLike
instead of Promise
to maintain compatibility with:
- Native JavaScript Promises
- Alternative promise libraries (e.g., Bluebird)
- Any Promise/A+ compliant implementation
This provides flexibility while ensuring standard promise behavior is maintained.
Key benefits:
- Works across different promise implementations (good for integrating legacy code)
- Maintains type safety while being less restrictive
In order to use async function you need to replace PromiseLike
with Promise
:
// MyDatabaseLockAdapter.ts
import type {
ILockData,
IDatabaseLockAdapter,
} from "@daiso-tech/core/lock/contracts";
export class MyDatabaseLockAdapter implements IDatabaseLockAdapter {
async insert(
key: string,
owner: string,
expiration: Date | null,
): Promise<void> {
throw new Error("Method not implemented.");
}
async update(
key: string,
owner: string,
expiration: Date | null,
): Promise<number> {
throw new Error("Method not implemented.");
}
async remove(key: string, owner: string | null): Promise<void> {
throw new Error("Method not implemented.");
}
async refresh(
key: string,
owner: string,
expiration: Date,
): Promise<number> {
throw new Error("Method not implemented.");
}
async find(key: string): Promise<ILockData | null> {
throw new Error("Method not implemented.");
}
}
Testing your custom IDatabaseLockAdapter
We provide a complete test suite to verify your event bus adapter implementation. Simply use the databaseLockAdapterTestSuite
function:
- Preconfigured Vitest test cases
- Standardized event bus behavior validation
- Common edge case coverage
Usage example:
import { beforeEach, describe, expect, test } from "vitest";
import { databaseLockAdapterTestSuite } from "@daiso-tech/core/lock/test-utilities";
import { MyDatabaseLockAdapter } from "./MyDatabaseLockAdapter.js";
describe("class: MyDatabaseLockAdapter", () => {
databaseLockAdapterTestSuite({
createAdapter: async () => {
return new MyDatabaseLockAdapter(),
},
test,
beforeEach,
expect,
describe,
});
});
Implementing your custom ILockProvider class
In some cases, you may need to implement a custom LockProvider
class to optimize performance for your specific technology stack. You can then directly implement the ILockProvider
contract.
Testing your custom ILockProvider class
We provide a complete test suite to verify your custom event bus class implementation. Simply use the lockProviderTestSuite
function:
- Preconfigured Vitest test cases
- Standardized event bus behavior validation
- Common edge case coverage
Usage example:
// filename: MyLockProvider.test.ts
import { beforeEach, describe, expect, test } from "vitest";
import { lockProviderTestSuite } from "@daiso-tech/core/lock/test-utilities";
import { MyLockProvider } from "./MyLockProvider.js";
describe("class: MyLockProvider", () => {
lockProviderTestSuite({
createLockProvider: () => new MyLockProvider(),
test,
beforeEach,
expect,
describe,
});
});